package com.fw.service.configuration.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.fw.service.applicationlog.ApplicationLogService;
import com.fw.service.applicationlog.bean.ApplicationLogBean;
import com.fw.service.auditlog.AuditLogService;
import com.fw.service.auditlog.bean.AuditLogBean;
import com.fw.service.bean.EntryBean;
import com.fw.service.bean.ErrorBean;
import com.fw.service.configuration.ConfigurationService;
import com.fw.service.formvalidator.FormValidatorService;
import com.fw.service.globalsetting.GlobalSettingService;
import com.fw.service.globalsetting.bean.GlobalSettingBean;
import com.fw.service.passwordpolicy.PasswordPolicyService;
import com.fw.service.passwordpolicy.bean.PasswordPolicyBean;
import com.fw.service.persistence.dto.Error;
import com.fw.service.property.PropertyService;
import com.fw.util.DateUtils;
import com.fw.util.StringUtils;

public class ConfigurationServiceImpl implements ConfigurationService {

    @Autowired
    private PropertyService propertyService;
    @Autowired
    private PasswordPolicyService passwordPolicyService;
    @Autowired
    private AuditLogService auditLogService;
    @Autowired
    private ApplicationLogService applicationLogService;
    @Autowired
    private FormValidatorService formValidatorService;
    @Autowired
    private GlobalSettingService globalSettingService;

    @Override
    public List<EntryBean<String, Serializable>> updatePasswordPolicy(PasswordPolicyBean passwordPolicyBean) {
	String clazz = ConfigurationService.class.getName();
	String method = "updatePasswordPolicy";
	List<EntryBean<String, Serializable>> entryBeans = null;
	try {
	    if (passwordPolicyBean != null) {
		entryBeans = new ArrayList<EntryBean<String, Serializable>>();
		// validate
		List<Error> errors = formValidatorService.validate(clazz, method, passwordPolicyBean);
		List<ErrorBean> errorBeans = new ArrayList<ErrorBean>();
		if (errors != null && !errors.isEmpty()) {
		    for (Error error : errors) {
			ErrorBean errorBean = new ErrorBean();
			BeanUtils.copyProperties(error, errorBean);
			errorBeans.add(errorBean);
		    }
		}
		if (errorBeans != null && !errorBeans.isEmpty()) {
		    entryBeans.add(new EntryBean<String, Serializable>(List.class.getName() + "." + ErrorBean.class.getName(),
			    (Serializable) errorBeans));
		} else {
		    Date currentDate = DateUtils.getCurrentDate();
		    String currentDateStr = StringUtils.formatDate(currentDate, StringUtils.PATTERN_DATETIME_PERSISTENCE);
		    passwordPolicyBean = passwordPolicyService.setPasswordPolicy(passwordPolicyBean);
		    // audit log
		    String logActionType = propertyService.getProperty("auditlog." + clazz + "." + method);
		    if (logActionType != null) {
			AuditLogBean auditLogBean = new AuditLogBean();
			auditLogBean.setLogActionType(logActionType);
			auditLogBean.setDescription("Password Policy updated by " + passwordPolicyBean.getLoginUsername());
			auditLogBean.setGroupId(passwordPolicyBean.getLoginRoleId());
			auditLogBean.setUserId(passwordPolicyBean.getLoginUserId());
			auditLogBean.setDateTime(currentDateStr);
			auditLogBean.setUserIp(passwordPolicyBean.getUserIp());
			auditLogService.createAuditLog(auditLogBean);
		    }
		    entryBeans.add(new EntryBean<String, Serializable>(passwordPolicyBean.getClass().getName(), passwordPolicyBean));
		}
	    }
	} catch (Exception e) {
	    ApplicationLogBean applicationLogBean = new ApplicationLogBean();
	    applicationLogBean.setType(ApplicationLogBean.TYPE_ERROR);
	    applicationLogBean.setClazz(clazz);
	    applicationLogBean.setMethod(method);
	    applicationLogBean.setMessage(e.getMessage());
	    applicationLogService.createApplicationLog(applicationLogBean);
	}
	return entryBeans;
    }

    @Override
    public List<EntryBean<String, Serializable>> updateGlobalSetting(GlobalSettingBean globalSettingBean) {
	String clazz = ConfigurationService.class.getName();
	String method = "updateGlobalSetting";
	List<EntryBean<String, Serializable>> entryBeans = null;
	try {
	    if (globalSettingBean != null) {
		entryBeans = new ArrayList<EntryBean<String, Serializable>>();
		// validate
		List<Error> errors = formValidatorService.validate(clazz, method, globalSettingBean);
		List<ErrorBean> errorBeans = new ArrayList<ErrorBean>();
		if (errors != null && !errors.isEmpty()) {
		    for (Error error : errors) {
			ErrorBean errorBean = new ErrorBean();
			BeanUtils.copyProperties(error, errorBean);
			errorBeans.add(errorBean);
		    }
		}
		if (errorBeans != null && !errorBeans.isEmpty()) {
		    entryBeans.add(new EntryBean<String, Serializable>(List.class.getName() + "." + ErrorBean.class.getName(),
			    (Serializable) errorBeans));
		} else {
		    Date currentDate = DateUtils.getCurrentDate();
		    String currentDateStr = StringUtils.formatDate(currentDate, StringUtils.PATTERN_DATETIME_PERSISTENCE);
		    globalSettingBean = globalSettingService.setGlobalSetting(globalSettingBean);
		    // audit log
		    String logActionType = propertyService.getProperty("auditlog." + clazz + "." + method);
		    if (logActionType != null) {
			AuditLogBean auditLogBean = new AuditLogBean();
			auditLogBean.setLogActionType(logActionType);
			auditLogBean.setDescription("Global Setting updated by " + globalSettingBean.getLoginUsername());
			auditLogBean.setGroupId(globalSettingBean.getLoginRoleId());
			auditLogBean.setUserId(globalSettingBean.getLoginUserId());
			auditLogBean.setDateTime(currentDateStr);
			auditLogBean.setUserIp(globalSettingBean.getUserIp());
			auditLogService.createAuditLog(auditLogBean);
		    }
		    entryBeans.add(new EntryBean<String, Serializable>(globalSettingBean.getClass().getName(), globalSettingBean));
		}
	    }
	} catch (Exception e) {
	    ApplicationLogBean applicationLogBean = new ApplicationLogBean();
	    applicationLogBean.setType(ApplicationLogBean.TYPE_ERROR);
	    applicationLogBean.setClazz(clazz);
	    applicationLogBean.setMethod(method);
	    applicationLogBean.setMessage(e.getMessage());
	    applicationLogService.createApplicationLog(applicationLogBean);
	}
	return entryBeans;
    }

}
